<?php

namespace app\health\controller;

use app\health\model\HealthCouponList;
use app\health\model\HealthUser;
use app\health\model\HealthUserAccount;
use app\health\model\HealthUserIdCard;
use app\health\model\HealthUserSignIn;
use app\health\model\HealthUserTask;
use app\health\model\HealthUserWithdraw;
use app\health\model\HealthWebsiteTask;
use app\health\model\MasterUser;
use app\health\service\ConfigService;
use app\health\validate\UserValidate;
use Exception;
use think\Db;

class User extends ApiBase
{
    protected $noNeedLogin = ['signInList'];

    /**
     * 会员信息
     * @Author 张旭鹏
     * @DateTime 2023-06-13
     */
    public function info()
    {
        $idCard = $this->auth->id_card ?: '';
        $this->success('', [
            'id'                => $this->auth->id,
            'code'              => $this->auth->code,
            'master_user_id'    => MasterUser::getMasterUserId($this->auth->mobile),
            'is_bind'           => empty($idCard) ? 0 : 1,
            'real_name'         => $this->auth->real_name,
            'id_card'           => $idCard,
            'mobile'            => $this->auth->mobile,
            'nickname'          => $this->auth->nickname,
            'avatar'            => $this->auth->avatar,
            'balance'           => $this->auth->balance,
            'virtually_coin'    => $this->auth->virtually_coin,
            'sign_in_day'       => $this->auth->sign_in_day,
            'session_key'       => $this->auth->session_key,
            'user_coupon_count' => count(HealthCouponList::getCanUseCoupon($this->auth->id))
        ]);
    }

    /**
     * 签到
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function signIn()
    {
        //查询今日签到记录
        $sign = HealthUserSignIn::where('user_id', $this->auth->id)->whereTime('createtime', 'd')->find();
        if ($sign) {
            $this->error('今日已签到');
        }
        // 获取签到规则
        $signInRules = ConfigService::signInRuleConfig();
        // 获取已签到天数
        $signInDay = $this->auth->sign_in_day ?: 0;
        if ($signInDay > 0 && !HealthUserSignIn::where('user_id', $this->auth->id)->where('day', $this->auth->sign_in_day)->whereTime('createtime', 'yesterday')->find()) {
            $signInDay = 0;
        }
        // 已签到天数
        $signInDay  = (int)$signInDay + 1;
        $rewardType = $signInRules['reward_type'];
        $reward     = $signInRules['reward'];
        $coiled     = $signInRules['coiled']; //连签规则
        usort($coiled, function ($current, $next) {
            return $current['day'] > $next['day'];
        });
        if ($signInDay > $coiled[count($coiled) - 1]['day']) {
            $signInDay = 1;
        }
        foreach ($coiled as $item) {
            if ($signInDay === (int)$item['day']) {
                $rewardType = $item['reward_type'];
                $reward     = $item['reward'];
                break;
            }
        }
        if (is_array($reward)) {
            $reward = $reward[random_int(0, count($reward) - 1)];
        }
        //添加签到记录
        HealthUserSignIn::create([
            'user_id'     => $this->auth->id,
            'reward_type' => $rewardType,
            'reward'      => $reward,
            'day'         => $signInDay,
            'createtime'  => time()
        ]);
        if ($rewardType > 0 && $reward > 0) {
            // 存在签到奖励
            $desc  = $signInDay === $coiled[count($coiled) - 1]['day'] ? '连续签到' . $coiled[count($coiled) - 1]['day'] . '天奖励' : '';
            $field = [1 => 'balance', 2 => 'virtually_coin'];
            HealthUser::where('id', $this->auth->id)->inc('sign_in_day_total')->inc($field[$rewardType], $reward)->update([
                'sign_in_day'  => $signInDay,
                'last_sign_in' => time()
            ]);
            HealthUserAccount::income(
                $this->auth->id,
                HealthUserAccount::FORM_TYPE_SIGNIN,
                $rewardType === 1 ? HealthUserAccount::ACCOUNT_TYPE_BALANCE : HealthUserAccount::ACCOUNT_TYPE_VIRTUALLY,
                $reward,
                $desc
            );
        } else {
            HealthUser::where('id', $this->auth->id)->inc('sign_in_day_total')->update([
                'sign_in_day'  => $signInDay,
                'last_sign_in' => time()
            ]);
        }
        $this->success('签到成功', ['reward' => $reward, 'reward_type' => $rewardType, 'tips' => '连续签到7天可获得最高88元红包']);
    }

    /**
     * 签到规则列表
     */
    public function signInList()
    {
        //今天是否签到
        $todayIsSignIn = 0;
        // 连签天数
        $signInDays = 0;
        // 获取签到规则
        $signInRules = ConfigService::signInRuleConfig();
        // 连签规则
        $coiled = $signInRules['coiled'];
        usort($coiled, function ($current, $next) {
            return $current['day'] > $next['day'];
        });

        if ($this->auth->id) {
            // 查询今日是否签到
            $todayIsSignIn = HealthUserSignIn::where('user_id', $this->auth->id)->whereTime('createtime', 'd')->count() > 0 ? 1 : 0;
            // 查询已签到天数
            $signInDays = $this->auth->sign_in_day;
            // 查询昨日是否签到
            $yesterdayIsSignIn = HealthUserSignIn::where('user_id', $this->auth->id)->whereTime('createtime', 'yesterday')->count() > 0 ? 1 : 0;
            if ($signInDays >= 1 && $todayIsSignIn == 0 && $yesterdayIsSignIn == 0) { //断签归0
                $signInDays = 0;
            }
            if ($signInDays >= $coiled[count($coiled) - 1]['day'] && $todayIsSignIn !== 1) {
                $signInDays = 0;
            }
        }
        $days = [
            1 => [
                'day'         => 1,
                'name'        => '第一天',
                'is_sign_in'  => $signInDays >= 1 ? 1 : 0,
                'icon'        => '',
                'reward_type' => $signInRules['reward_type'],
                'reward'      => $signInRules['reward'],
                'random'      => is_array($signInRules['reward']) ? 1 : 0
            ]
        ];
        foreach ($coiled as $item) {
            $days[$item['day']] = [
                'day'         => $item['day'],
                'name'        => '第' . num_to_chinese($item['day']) . '天',
                'is_sign_in'  => $item['day'] <= $signInDays ? 1 : 0,
                'icon'        => '',
                'reward_type' => $item['reward_type'],
                'reward'      => is_array($item['reward']) ? max($item['reward']) : $item['reward'],
                'random'      => is_array($item['reward']) ? 1 : 0
            ];
        }
        $days[count($days)]['icon'] = request()->domain() . '/assets/img/red_envelope.png?v=1';
        usort($days, function ($current, $next) {
            return $current['day'] > $next['day'];
        });
        $this->success('success', [
            //连签天数天数
            'sign_in_day'   => $signInDays,
            //今日是否签到
            'today_sign_in' => $todayIsSignIn,
            //签到列表
            'days'          => $days,
            'explain'       => [
                '本活动为鑫互助小程序签到礼包活动，每日签到可获得平台积分，连续签到7日有红包礼品奖励，红包金额为0-88元不等的随机红包，红包领取后可在“我的”——“我的红包”内查看。红包可用于提现或在鑫互助小程序商城购物使用。',
                '签到单周期为7天，完成单周期签到任务后，可开始新周期签到任务，上一周期所积累的签到次数将自动清零。',
                '活动期间，签到红包发放情况根据活动开展情况调整，具体发放情况以鑫互助小程序实际发放为准，优惠券发放时间以鑫互助小程序实际发放时间为准。'
            ]
        ]);
    }

    /**
     * 签到记录
     */
    public function sign_record()
    {
        $paginate = HealthUserSignIn::where('user_id', $this->auth->id)
            ->order('id', 'desc')
            ->paginate(10)
            ->each(function ($item) {
                $item->createtime = date('Y-m-d H:i:s', $item->createtime);
            });
        $this->success('success', $paginate);
    }

    /**
     * 添加就诊人信息
     * @return void
     * @throws \RedisException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function addIdCard()
    {
        $params = (new UserValidate())->goCheck('id_card');
        $idCard = $params['id_card'];
        $birth  = strlen($idCard) === 15 ? ('19' . substr($idCard, 6, 6)) : substr($idCard, 6, 8);
        $sex    = (substr($idCard, strlen($idCard) - 2, 1) % 2) === 0 ? '女' : '男';
        //更新用户身份信息
        HealthUser::where('id', $this->auth->id)->update([
            'real_name' => $params['real_name'],
            'id_card'   => $params['id_card']
        ]);
        //更新用户身份证
        $idCardRow = HealthUserIdCard::where('user_id', $this->auth->id)->find();
        if (!$idCardRow) {
            HealthUserIdCard::create([
                'user_id'   => $this->auth->id,
                'real_name' => $params['real_name'],
                'id_card'   => $params['id_card'],
                'birthday'  => date('Y-m-d', strtotime($birth)),
                'gender'    => (substr($idCard, strlen($idCard) - 2, 1) % 2) === 0 ? '2' : '1',
            ]);
            queue_custom('app\common\job\WebsiteTaskJob', [
                'user_id'      => $this->auth->id,
                'complete_way' => 2
            ]);
        } else {
            $idCardRow->real_name  = $params['real_name'];
            $idCardRow->id_card    = $params['id_card'];
            $idCardRow->birthday   = date('Y-m-d', strtotime($birth));
            $idCardRow->gender     = (substr($idCard, strlen($idCard) - 2, 1) % 2) === 0 ? '2' : '1';
            $idCardRow->updated_at = date('Y-m-d H:i:s');
            $idCardRow->save();
        }
        //更新主用户库身份数据
        MasterUser::where('id', MasterUser::getMasterUserId($this->auth->mobile))->update([
            'name'     => $params['real_name'],
            'card'     => $params['id_card'],
            'birthday' => date('Y-m-d', strtotime($birth)),
            'sex'      => $sex,
            'third_id' => '121' . $this->auth->mobile,
            'is_bind'  => 1,
        ]);
        $this->success('更新成功');
    }

    /**
     * 申请提现
     * @Author 张旭鹏
     * @DateTime 2023-06-14
     */
    public function withdraw()
    {
        try {
            Db::startTrans();
            $user           = HealthUser::where('id', $this->auth->id)->lock(true)->find();
            $money          = $user['balance'];
            $withdrawConfig = ConfigService::getWithdrawConfig();
            if ($money < $withdrawConfig['min']) {
                throw new Exception('提现金额不能少于 ' . $withdrawConfig['min'] . '元');
            }
            if ($money > $withdrawConfig['max']) {
                $money = $withdrawConfig['max'];
            }
            if ($money > $withdrawConfig['max']) {
                throw new Exception('提现金额不能大于 ' . $withdrawConfig['max'] . '元');
            }
            HealthUserWithdraw::create([
                'user_id'  => $user['id'],
                'order_no' => create_trade_no('T'),
                'money'    => $money
            ]);
            HealthUserAccount::expend(
                $user->id,
                HealthUserAccount::FORM_TYPE_WITHDRAW,
                HealthUserAccount::ACCOUNT_TYPE_BALANCE,
                $money
            );
            $user->balance = bcsub($user->balance, $money, 2);
            $user->save();
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('申请成功');
    }
}
